package com.gome.boot.config.mq.rocketmq;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.gome.utils.SerializeUtil;

import java.nio.charset.Charset;

/**
 * 序列化类型枚举.
 * <br/>尽量不要使用STRING_GBK|STRING_ISO三种序列化编码方式进行消息的发送.
 * <br/>考虑到外部系统发送的消息序列化编码方式不确定，所以有可能会需要采用STRING_GBK|STRING_ISO两类反序列化方式进行消息内容的解码.
 *
 * @author baoxiufeng
 */
public enum SerializeType {
    STRING,
    STRING_UTF,
    STRING_GBK,
    STRING_ISO,
    FASTJSON,
    OBJECT;

    private static final Charset UTF = Charset.forName("UTF-8");
    private static final Charset GBK = Charset.forName("GBK");
    private static final Charset ISO = Charset.forName("ISO8859-1");
    private static final Feature[] FASTJSON_FEATURE_DESERIALIZE = new Feature[0];
    private static final SerializerFeature[] FASTJSON_FEATURE_SERIALIZE = new SerializerFeature[]{SerializerFeature.WriteClassName, SerializerFeature.BrowserCompatible};

    /**
     * 序列化给定对象为字节数组.
     *
     * @param messageObject 消息对象
     * @return 序列化后的字节数组
     */
    public byte[] serialize(Object messageObject) {
        byte[] jsonBytes;
        switch(this) {
            case STRING:
            case STRING_UTF:
                jsonBytes = messageObject.toString().getBytes(UTF);
                break;
            case STRING_GBK:
                jsonBytes = messageObject.toString().getBytes(GBK);
                break;
            case STRING_ISO:
                jsonBytes = messageObject.toString().getBytes(ISO);
                break;
            case FASTJSON:
                jsonBytes = JSON.toJSONBytes(messageObject, FASTJSON_FEATURE_SERIALIZE);
                break;
            case OBJECT:
                jsonBytes = SerializeUtil.serialize(messageObject);
                break;
            default:
                throw new UnsupportedOperationException("serializeType is not supported. ");
        }
        return jsonBytes;
    }

    /**
     * 反序列化字节数组为消费内容对象.
     *
     * @param messageBody 待反序列化的字节数组
     * @return 反序列化后的消费内容对象
     */
    public Object deserialize(byte[] messageBody) {
        Object obj = null;
        switch (this) {
            case STRING:
            case STRING_UTF:
                obj = new String(messageBody);
                break;
            case STRING_GBK:
                obj = new String(new String(messageBody).getBytes(GBK), UTF);
                break;
            case STRING_ISO:
                obj = new String(new String(messageBody).getBytes(ISO), UTF);
                break;
            case FASTJSON:
                obj = JSON.parseObject(messageBody, Object.class, FASTJSON_FEATURE_DESERIALIZE);
                break;
            case OBJECT:
                obj = SerializeUtil.deserializeObject(messageBody);
                break;
            default:
                throw new UnsupportedOperationException("serializeType is not supported. ");
        }
        return obj;
    }
}
